package com.tsq.weixin.provider.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tsq.web.base.service.impl.BaseServiceImpl;
import com.tsq.weixin.api.model.MsgReplyRule;
import com.tsq.weixin.provider.mapper.MsgReplyRuleMapper;
import com.tsq.weixin.provider.service.MsgReplyRuleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional(rollbackFor = Exception.class)
public class MsgReplyRuleServiceImpl extends BaseServiceImpl<MsgReplyRuleMapper, MsgReplyRule> implements MsgReplyRuleService {

    @Autowired
    private MsgReplyRuleMapper msgReplyRuleMapper;

    @Override
    public IPage<MsgReplyRule> queryPage(MsgReplyRule msgReplyRule) {

        String matchValue = msgReplyRule.getMatchValue();
        String appid = msgReplyRule.getAppid();
        long currentPage = msgReplyRule.getCurrent();
        long pageSize = msgReplyRule.getSize();

        return this.baseMapper.selectPage(new Page<>(currentPage, pageSize),new QueryWrapper<MsgReplyRule>()
                .eq(!StringUtils.isEmpty(appid), "appid", appid)
                .or()
                .apply("appid is null or appid = ''")
                .like(!StringUtils.isEmpty(matchValue), "match_value", matchValue)
                .orderByDesc("update_time"));
    }

    @Override
    public MsgReplyRule getById(Integer ruleId) {
        return this.baseMapper.selectOne(new LambdaQueryWrapper<MsgReplyRule>().eq(MsgReplyRule::getRuleId,ruleId));
    }

    @Override
    public boolean save(MsgReplyRule msgReplyRule) {
        return super.save(msgReplyRule);
    }

    @Override
    public boolean updateById(MsgReplyRule msgReplyRule) {
        return super.updateById(msgReplyRule);
    }

    @Override
    public boolean removeByIds(List<Integer> asList) {
        return super.removeByIds(asList);
    }


    @Override
    public List<MsgReplyRule> getRules() {
        return msgReplyRuleMapper.selectList(new QueryWrapper<MsgReplyRule>().orderByDesc("rule_id"));
    }

    @Override
    public List<MsgReplyRule> getMatchedRules(String appId, boolean exactMatch, String keywords) {
        LocalTime now = LocalTime.now();
        return this.getValidRules().stream()
                .filter(rule->StringUtils.isEmpty(rule.getAppid()) || appId.equals(rule.getAppid())) // 检测是否是对应公众号的规则，如果appId为空则为通用规则
                .filter(rule->null == rule.getEffectTimeStart() || rule.getEffectTimeStart().toLocalTime().isBefore(now))// 检测是否在有效时段，effectTimeStart为null则一直有效
                .filter(rule->null == rule.getEffectTimeEnd() || rule.getEffectTimeEnd().toLocalTime().isAfter(now)) // 检测是否在有效时段，effectTimeEnd为null则一直有效
                .filter(rule->isMatch(exactMatch || rule.isExactMatch(),rule.getMatchValue().split(","),keywords)) //检测是否符合匹配规则
                .collect(Collectors.toList());
    }

    @Override
    public List<MsgReplyRule> getValidRules() {

        return msgReplyRuleMapper.selectList(
                new QueryWrapper<MsgReplyRule>()
                        .eq("status", 1)
                        .isNotNull("match_value")
                        .ne("match_value", "")
                        .orderByDesc("priority"));
    }


    /**
     * 检测文字是否匹配规则
     * 精确匹配时，需关键词与规则词语一致
     * 非精确匹配时，检测文字需包含任意一个规则词语
     *
     * @param exactMatch 是否精确匹配
     * @param ruleWords  规则列表
     * @param checkWords 需检测的文字
     * @return boolean
     */
    public static boolean isMatch(boolean exactMatch, String[] ruleWords, String checkWords) {
        if (StringUtils.isEmpty(checkWords)) return false;
        for (String words : ruleWords) {
            if (exactMatch && words.equals(checkWords)) return true;//精确匹配，需关键词与规则词语一致
            if (!exactMatch && checkWords.contains(words)) return true;//模糊匹配
        }
        return false;
    }

}
